package top.hekun.study.core.visitor.method.complex;

import org.objectweb.asm.MethodVisitor;

import static org.objectweb.asm.Opcodes.*;

/**
 * 〈清除 +0 无效语句〉
 *
 * @author: Sakura
 * @date: 2023/5/12
 */
public class MyMethodVisitor1 extends PatternMethodVisitor {
    private String thisClassName = this.getClass().getSimpleName();
    protected final static int SEEN_ICONST_0 = 1;

    protected MyMethodVisitor1(int api, MethodVisitor methodVisitor) {
        super(api, methodVisitor);
    }

    /**
     * 去掉 iconst_0 和iadd
     * 在 这个方法中 进行方法的变化
     * @param opcode
     */
    @Override
    public void visitInsn(int opcode) {
        System.out.println("state: " + state + "   opcode  " + opcode);
        // 对感兴趣的状态进行处理
        switch (state) {
            // 初始状态下
            case SEEN_NOTHING:
                // 如果命令是 iconst_0  就变化状态 并且抛弃 当前指令
                if (opcode == ICONST_0) {
                    state = SEEN_ICONST_0;
                    return;
                }
                break;
            // 如果当前状态是     SEEN_ICONST_0
            case SEEN_ICONST_0:
                // 如果命令是 IADD 则 抛弃 当前add指令 并且状态回到 处室状态
                if (opcode == IADD) {
                    state = SEEN_NOTHING;
                    return;
                }
                // 如果在 SEEN_ICONST_0 的状态下 还是收到了 ICONST_0 指令, 则运行一个ICONST_0 指令, 相当于 收到2个 ICONST_0, 只 执行一个,还是继续扣留一个
                else if (opcode == ICONST_0) {
                    // 越过父类visitInsn方法,在给 mv. 执行
                    mv.visitInsn(ICONST_0);
                    return;
                }
                break;
        }
        // 不感兴趣的状态 ,交给父类处理 , 会执行visitInsn() 在给 mv. 执行
        super.visitInsn(opcode);
    }


    /**
     * 兼职状态的初始化
     */
    @Override
    public void visitInsn() {
        System.out.println("state: " + state);
      // 当 state == SEEN_ICONST_0 的时候, 执行一个ICONST_0 指令
        if (state == SEEN_ICONST_0) {
            mv.visitInsn(ICONST_0);
        }
        //  首次进入的时候  赋值 state= SEEN_NOTHING
        state = SEEN_NOTHING;
    }
}
